package com.android.nearshop.app.adapter.map;

import android.content.Context;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.drawable.BitmapDrawable;
import android.location.Location;
import android.util.Log;
import android.view.MotionEvent;

import com.android.nearshop.R;
import com.android.nearshop.util.CycledThread;
import com.android.nearshop.util.CycledThread.OnTimeoutListener;
import com.android.nearshop.util.LocationUtils;
import com.baidu.mapapi.GeoPoint;
import com.baidu.mapapi.MapController;
import com.baidu.mapapi.MapView;
import com.baidu.mapapi.Overlay;

public class PoiOverlay extends Overlay
{
    private static final String TAG = "PoiOverlay";
    // 长按成员
    private float lastX;
    private float lastY;
    private float thisX;
    private float thisY;
    private long lastDownTime;
    private long thisEventTime;
    private long longPressTime = 3000;
    private boolean isSelected = false;
    private boolean isMoving = false;
    /** 画笔*/
    private Paint mPaint;   
    private static final int MAX_RADUIS = 100;
    private static final int MIN_RADUIS = 50;
    private int  mRaduis = MAX_RADUIS;
    private int  mDalt = -10;
    private MapView mMapView;
    
    private BitmapDrawable poiBmp;
    private GeoPoint currentGp;
    private GeoPoint firstGp;
    private OnLocSelListener gpSelectListener;
    private boolean isVisibleIn = false;
    private CycledThread checkThread = null;

    public PoiOverlay(Context context)
    {
        poiBmp = (BitmapDrawable) context.getResources().getDrawable(R.drawable.poi);
        mPaint = new Paint();
        /* 去锯齿 */  
        mPaint.setAntiAlias(true);
        
        mPaint.setDither(true);
        /* 设置paint的颜色 */  
        mPaint.setColor(0x88A6F6B3);
        /* 设置paint的外框宽度 */  
        mPaint.setStrokeWidth(2);
        /* 设置paint的 style 为STROKE：空心 */
        mPaint.setStyle(Paint.Style.FILL);
        
        mPaint.setStrokeJoin(Paint.Join.ROUND);
        mPaint.setStrokeCap(Paint.Cap.ROUND);
    }

    public synchronized void setOnLocSelListener(OnLocSelListener l)
    {
        gpSelectListener = l;
    }

    /**
     * 设置显示的位置
     * 
     * @param location
     */
    public void setShowLocation(Location location)
    {
        if (location == null) return;

        currentGp = new GeoPoint((int) (location.getLatitude() * 1E6),
                (int) (location.getLongitude() * 1E6));

        isVisibleIn = false;
    }

    public boolean onTouchEvent(MotionEvent event, MapView mapView)
    {
        mMapView = mapView;
        if (gpSelectListener != null)
        {
            if (event.getAction() == MotionEvent.ACTION_UP)
            {
                Log.d(TAG, "-->up");
                // 释放时为选中状态
                resetLongPressStatus();
            } else
            if(event.getAction() == MotionEvent.ACTION_DOWN)
            {
                Log.d(TAG, "-->down");
                // 按下开始计时               
                lastX = event.getX();
                lastY = event.getY();
                isMoving = false;
                lastDownTime = System.currentTimeMillis();
                firstGp = LocationUtils.getGeoPoint(mapView,(int) event.getX(), (int) event.getY());
                startCheckDelay();
            }
            else
            if (event.getAction() == MotionEvent.ACTION_MOVE)
            {
                // 移动时为未选中状态
                if(!isSelected)
                {
                    Log.d(TAG, "-->move");
                    thisX = event.getX();
                    thisY = event.getY();                    
                    thisEventTime = System.currentTimeMillis();
                    if(isLongPressed())
                    {
                        isSelected = true;
                        currentGp = LocationUtils.getGeoPoint(mapView,(int) event.getX(), (int) event.getY());
                        gpSelectListener.onSelect(currentGp);
                    }
                }
            }else 
            {
                Log.d(TAG, "-->other");
            }
        }
        return super.onTouchEvent(event, mapView);
    };

    /**
     * 判断是否有长按动作发生
     * @param lastDownTime 按下时间
     * @param thisEventTime 移动时间
     * @param longPressTime 判断长按时间的阀值
     */
    private boolean isLongPressed()
    {      
      long intervalTime = thisEventTime - lastDownTime;
      return  ( !isMoving() && intervalTime >= longPressTime);
    }
    
    /**
     * 是否在有限范围内移动
     * @param lastX 按下时X坐标
     * @param lastY 按下时Y坐标
     * @param thisX 移动时X坐标
     * @param thisY 移动时Y坐标
     * @return
     */
    private boolean isMoving()
    {
        float offsetX = Math.abs(thisX - lastX);
        float offsetY = Math.abs(thisY - lastY);
        
        return isMoving = !(offsetX <=4 && offsetY<=4);
    }
    
    // 重置长按的状态
    private void resetLongPressStatus()
    {
        isSelected = false;
        isMoving = false;
        lastX = 0f;
        lastY = 0f;
        lastDownTime = 0L;
        thisX = 0f;
        thisY = 0f;
        thisEventTime = 0L;
        stopCheck();
    }
    
    private void startCheckDelay()
    {
        mMapView.postDelayed(new Runnable()
        {          
            @Override
            public void run()
            {
                if(!isMoving && lastX > 0)
                {
                    startCheck();
                }
            }
        }, 300);               
    }
    
    private void startCheck()
    {
        if(checkThread == null )
        {
            checkThread = new CycledThread(new Runnable()
            {
                @Override
                public void run()
                {
                    mRaduis += mDalt;
                    if(mRaduis < MIN_RADUIS || mRaduis > MAX_RADUIS)
                    {
                        mDalt = -mDalt;
                    }
                    mMapView.postInvalidateDelayed(200);
                }
            }, 100, 3000, 
                    new OnTimeoutListener()
            {
                @Override
                public void onTimeout()
                {              
                    if(!isSelected)
                    {
                        isSelected = true;
                        currentGp = firstGp;
                        gpSelectListener.onSelect(firstGp);
                    }
                    mMapView.postInvalidate();
                }
            });
            checkThread.start();
        }
    }
    
    private void stopCheck()
    {
        if(checkThread != null)
        {
            checkThread._stop();
            checkThread = null;
        }
    }
    
    public void draw(android.graphics.Canvas canvas, MapView mapView,
            boolean shadow)
    {
        // 画定位图标
        if (currentGp != null)
        {
            Point point = LocationUtils.getPoint(mapView, currentGp);
            // point.x-poiBmp.getIntrinsicWidth()/2 --> point.x : 选取的点几位定位点
            canvas.drawBitmap(poiBmp.getBitmap(), point.x-poiBmp.getIntrinsicWidth()/2,
                    point.y - poiBmp.getIntrinsicHeight(), null);

            if (!isVisibleIn && !LocationUtils.isVisibleIn(mapView, currentGp))
            {
                MapController controller = mapView.getController();
                controller.animateTo(currentGp);
                isVisibleIn = true;
            }
        }
        // 画选择等候效果
        if(lastX > 0 && !isSelected && !isMoving)
        {
            canvas.drawCircle( lastX, lastY , mRaduis , mPaint);
        }
        super.draw(canvas, mapView, shadow);
    };

    /** 用户由屏幕选取GeoPoint监听器，当释放时，触发事件 */
    public static interface OnLocSelListener
    {
        void onSelect(GeoPoint geo);
    }
}